<!DOCTYPE html>

<html>
<head>
  <title>regexper.js</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  <link rel="stylesheet" media="all" href="../docco.css" />
</head>
<body>
  <div id="container">
    <div id="background"></div>
    
    <ul class="sections">
        
          <li id="title">
              <div class="annotation">
                  <h1>regexper.js</h1>
              </div>
          </li>
        
        
        
        <li id="section-1">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-1">&#182;</a>
              </div>
              <p>The Regexper class manages the top-level behavior for the entire
application. This includes event handlers for all user interactions.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
<span class="hljs-keyword">import</span> util <span class="hljs-keyword">from</span> <span class="hljs-string">'./util.js'</span>;
<span class="hljs-keyword">import</span> Parser <span class="hljs-keyword">from</span> <span class="hljs-string">'./parser/javascript.js'</span>;
<span class="hljs-keyword">import</span> _ <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Regexper</span> </span>{
  <span class="hljs-keyword">constructor</span>(root) {
    <span class="hljs-keyword">this</span>.root = root;
    <span class="hljs-keyword">this</span>.buggyHash = <span class="hljs-literal">false</span>;
    <span class="hljs-keyword">this</span>.form = root.querySelector(<span class="hljs-string">'#regexp-form'</span>);
    <span class="hljs-keyword">this</span>.field = root.querySelector(<span class="hljs-string">'#regexp-input'</span>);
    <span class="hljs-keyword">this</span>.error = root.querySelector(<span class="hljs-string">'#error'</span>);
    <span class="hljs-keyword">this</span>.warnings = root.querySelector(<span class="hljs-string">'#warnings'</span>);

    <span class="hljs-keyword">this</span>.links = <span class="hljs-keyword">this</span>.form.querySelector(<span class="hljs-string">'ul'</span>);
    <span class="hljs-keyword">this</span>.permalink = <span class="hljs-keyword">this</span>.links.querySelector(<span class="hljs-string">'a[data-action="permalink"]'</span>);
    <span class="hljs-keyword">this</span>.downloadSvg = <span class="hljs-keyword">this</span>.links.querySelector(<span class="hljs-string">'a[data-action="download-svg"]'</span>);
    <span class="hljs-keyword">this</span>.downloadPng = <span class="hljs-keyword">this</span>.links.querySelector(<span class="hljs-string">'a[data-action="download-png"]'</span>);

    <span class="hljs-keyword">this</span>.svgContainer = root.querySelector(<span class="hljs-string">'#regexp-render'</span>);
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-2">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-2">&#182;</a>
              </div>
              <p>Event handler for key presses in the regular expression form field.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  keypressListener(event) {</pre></div></div>
            
        </li>
        
        
        <li id="section-3">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-3">&#182;</a>
              </div>
              <p>Pressing Shift-Enter displays the expression.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> (event.shiftKey &amp;&amp; event.keyCode === <span class="hljs-number">13</span>) {
      event.returnValue = <span class="hljs-literal">false</span>;
      <span class="hljs-keyword">if</span> (event.preventDefault) {
        event.preventDefault();
      }

      <span class="hljs-keyword">this</span>.form.dispatchEvent(util.customEvent(<span class="hljs-string">'submit'</span>));
    }
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-4">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-4">&#182;</a>
              </div>
              <p>Event handler for key presses while focused anywhere in the application.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  documentKeypressListener(event) {</pre></div></div>
            
        </li>
        
        
        <li id="section-5">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-5">&#182;</a>
              </div>
              <p>Pressing escape will cancel a currently running render.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> (event.keyCode === <span class="hljs-number">27</span> &amp;&amp; <span class="hljs-keyword">this</span>.running) {
      <span class="hljs-keyword">this</span>.running.cancel();
    }
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-6">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-6">&#182;</a>
              </div>
              <p>Event handler for submission of the regular expression. Changes the URL
hash which leads to the expression being rendered.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  submitListener(event) {
    event.returnValue = <span class="hljs-literal">false</span>;
    <span class="hljs-keyword">if</span> (event.preventDefault) {
      event.preventDefault();
    }

    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">this</span>._setHash(<span class="hljs-keyword">this</span>.field.value);
    }
    <span class="hljs-keyword">catch</span>(e) {</pre></div></div>
            
        </li>
        
        
        <li id="section-7">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-7">&#182;</a>
              </div>
              <p>Failed to set the URL hash (probably because the expression is too
long). Turn off display of the permalink and just show the expression.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">this</span>.permalinkEnabled = <span class="hljs-literal">false</span>;
      <span class="hljs-keyword">this</span>.showExpression(<span class="hljs-keyword">this</span>.field.value);
    }
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-8">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-8">&#182;</a>
              </div>
              <p>Event handler for URL hash changes. Starts rendering of the expression.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  hashchangeListener() {
    <span class="hljs-keyword">let</span> expr = <span class="hljs-keyword">this</span>._getHash();

    <span class="hljs-keyword">if</span> (expr <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Error</span>) {
      <span class="hljs-keyword">this</span>.state = <span class="hljs-string">'has-error'</span>;
      <span class="hljs-keyword">this</span>.error.innerHTML = <span class="hljs-string">'Malformed expression in URL'</span>;
      util.track(<span class="hljs-string">'send'</span>, <span class="hljs-string">'event'</span>, <span class="hljs-string">'visualization'</span>, <span class="hljs-string">'malformed URL'</span>);
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">this</span>.permalinkEnabled = <span class="hljs-literal">true</span>;
      <span class="hljs-keyword">this</span>.showExpression(expr);
    }
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-9">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-9">&#182;</a>
              </div>
              <p>Binds all event listeners.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  bindListeners() {
    <span class="hljs-keyword">this</span>.field.addEventListener(<span class="hljs-string">'keypress'</span>, <span class="hljs-keyword">this</span>.keypressListener.bind(<span class="hljs-keyword">this</span>));
    <span class="hljs-keyword">this</span>.form.addEventListener(<span class="hljs-string">'submit'</span>, <span class="hljs-keyword">this</span>.submitListener.bind(<span class="hljs-keyword">this</span>));
    <span class="hljs-keyword">this</span>.root.addEventListener(<span class="hljs-string">'keyup'</span>, <span class="hljs-keyword">this</span>.documentKeypressListener.bind(<span class="hljs-keyword">this</span>));
    <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'hashchange'</span>, <span class="hljs-keyword">this</span>.hashchangeListener.bind(<span class="hljs-keyword">this</span>));
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-10">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-10">&#182;</a>
              </div>
              <p>Detect if <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=483304">https://bugzilla.mozilla.org/show_bug.cgi?id=483304</a> is in effect</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  detectBuggyHash() {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">window</span>.URL === <span class="hljs-string">'function'</span>) {
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">let</span> url = <span class="hljs-keyword">new</span> URL(<span class="hljs-string">'http://regexper.com/#%25'</span>);
        <span class="hljs-keyword">this</span>.buggyHash = (url.hash === <span class="hljs-string">'#%'</span>);
      }
      <span class="hljs-keyword">catch</span>(e) {
        <span class="hljs-keyword">this</span>.buggyHash = <span class="hljs-literal">false</span>;
      }
    }
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-11">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-11">&#182;</a>
              </div>
              <p>Set the URL hash. This method exists to facilitate automated testing
(since changing the URL can throw off most JavaScript testing tools).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  _setHash(hash) {
    location.hash = <span class="hljs-built_in">encodeURIComponent</span>(hash)
      .replace(<span class="hljs-regexp">/\(/g</span>, <span class="hljs-string">'%28'</span>)
      .replace(<span class="hljs-regexp">/\)/g</span>, <span class="hljs-string">'%29'</span>);
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-12">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-12">&#182;</a>
              </div>
              <p>Retrieve the current URL hash. This method is also mostly for supporting
automated testing, but also does some basic error handling for malformed
URLs.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  _getHash() {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">let</span> hash = location.hash.slice(<span class="hljs-number">1</span>)
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.buggyHash ? hash : <span class="hljs-built_in">decodeURIComponent</span>(hash);
    }
    <span class="hljs-keyword">catch</span>(e) {
      <span class="hljs-keyword">return</span> e;
    }
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-13">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-13">&#182;</a>
              </div>
              <p>Currently state of the application. Useful values are:</p>
<ul>
<li><code>&#39;&#39;</code> - State of the application when the page initially loads</li>
<li><code>&#39;is-loading&#39;</code> - Displays the loading indicator</li>
<li><code>&#39;has-error&#39;</code> - Displays the error message</li>
<li><code>&#39;has-results&#39;</code> - Displays rendered results</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  set state(state) {
    <span class="hljs-keyword">this</span>.root.className = state;
  }

  get state() {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.root.className;
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-14">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-14">&#182;</a>
              </div>
              <p>Start the rendering of a regular expression.</p>
<ul>
<li><strong>expression</strong> - Regular expression to display.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  showExpression(expression) {
    <span class="hljs-keyword">this</span>.field.value = expression;
    <span class="hljs-keyword">this</span>.state = <span class="hljs-string">''</span>;

    <span class="hljs-keyword">if</span> (expression !== <span class="hljs-string">''</span>) {
      <span class="hljs-keyword">this</span>.renderRegexp(expression).catch(util.exposeError);
    }
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-15">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-15">&#182;</a>
              </div>
              <p>Creates a blob URL for linking to a rendered regular expression image.</p>
<ul>
<li><strong>content</strong> - SVG image markup.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  buildBlobURL(content) {</pre></div></div>
            
        </li>
        
        
        <li id="section-16">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-16">&#182;</a>
              </div>
              <p>Blob object has to stick around for IE, so the instance is stored on the
<code>window</code> object.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-built_in">window</span>.blob = <span class="hljs-keyword">new</span> Blob([content], { <span class="hljs-attr">type</span>: <span class="hljs-string">'image/svg+xml'</span> });
    <span class="hljs-keyword">return</span> URL.createObjectURL(<span class="hljs-built_in">window</span>.blob);
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-17">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-17">&#182;</a>
              </div>
              <p>Update the URLs of the ‘download’ and ‘permalink’ links.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  updateLinks() {
    <span class="hljs-keyword">let</span> classes = _.without(<span class="hljs-keyword">this</span>.links.className.split(<span class="hljs-string">' '</span>), [<span class="hljs-string">'hide-download-svg'</span>, <span class="hljs-string">'hide-permalink'</span>]);
    <span class="hljs-keyword">let</span> svg = <span class="hljs-keyword">this</span>.svgContainer.querySelector(<span class="hljs-string">'.svg'</span>);</pre></div></div>
            
        </li>
        
        
        <li id="section-18">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-18">&#182;</a>
              </div>
              <p>Create the SVG ‘download’ image URL.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">this</span>.downloadSvg.parentNode.style.display = <span class="hljs-literal">null</span>;
      <span class="hljs-keyword">this</span>.downloadSvg.href = <span class="hljs-keyword">this</span>.buildBlobURL(svg.innerHTML);
    }
    <span class="hljs-keyword">catch</span>(e) {</pre></div></div>
            
        </li>
        
        
        <li id="section-19">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-19">&#182;</a>
              </div>
              <p>Blobs or URLs created from a blob URL don’t work in the current
browser. Giving up on the download link.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      classes.push(<span class="hljs-string">'hide-download-svg'</span>);
    }</pre></div></div>
            
        </li>
        
        
        <li id="section-20">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-20">&#182;</a>
              </div>
              <p>Create the PNG ‘download’ image URL.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">let</span> canvas = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'canvas'</span>);
      <span class="hljs-keyword">let</span> context = canvas.getContext(<span class="hljs-string">'2d'</span>);
      <span class="hljs-keyword">let</span> loader = <span class="hljs-keyword">new</span> Image;

      loader.width = canvas.width = <span class="hljs-built_in">Number</span>(svg.querySelector(<span class="hljs-string">'svg'</span>).getAttribute(<span class="hljs-string">'width'</span>));
      loader.height = canvas.height = <span class="hljs-built_in">Number</span>(svg.querySelector(<span class="hljs-string">'svg'</span>).getAttribute(<span class="hljs-string">'height'</span>));
      loader.onload = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-keyword">try</span> {
          context.drawImage(loader, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, loader.width, loader.height);
          canvas.toBlob(<span class="hljs-function"><span class="hljs-params">blob</span> =&gt;</span> {
            <span class="hljs-keyword">try</span> {
              <span class="hljs-built_in">window</span>.pngBlob = blob;
              <span class="hljs-keyword">this</span>.downloadPng.href = URL.createObjectURL(<span class="hljs-built_in">window</span>.pngBlob);
              <span class="hljs-keyword">this</span>.links.className = <span class="hljs-keyword">this</span>.links.className.replace(<span class="hljs-regexp">/\bhide-download-png\b/</span>, <span class="hljs-string">''</span>);
            }
            <span class="hljs-keyword">catch</span>(e) {}
          }, <span class="hljs-string">'image/png'</span>);

          <span class="hljs-keyword">let</span> image64 = canvas.toDataURL(<span class="hljs-string">'image/png'</span>,<span class="hljs-number">1</span>);
          <span class="hljs-keyword">this</span>.permalink.onclick = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
            <span class="hljs-keyword">let</span> transfer = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'input'</span>);
            transfer.value = <span class="hljs-string">`![<span class="hljs-subst">${location.toString()}</span>](<span class="hljs-subst">${image64}</span>)`</span>;
            <span class="hljs-built_in">document</span>.body.appendChild(transfer);
            transfer.focus();
            transfer.select();
            <span class="hljs-keyword">if</span> (<span class="hljs-built_in">document</span>.execCommand(<span class="hljs-string">'copy'</span>)) {
                <span class="hljs-built_in">document</span>.execCommand(<span class="hljs-string">'copy'</span>);
            }
            transfer.blur();
            <span class="hljs-built_in">document</span>.body.removeChild(transfer);
          }
        }
        <span class="hljs-keyword">catch</span>(e) {}
      };
      loader.src = <span class="hljs-string">'data:image/svg+xml,'</span> + <span class="hljs-built_in">encodeURIComponent</span>(svg.innerHTML);
      classes.push(<span class="hljs-string">'hide-download-png'</span>);
    }
    <span class="hljs-keyword">catch</span>(e) {}</pre></div></div>
            
        </li>
        
        
        <li id="section-21">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-21">&#182;</a>
              </div>
              <p>Create the ‘permalink’ URL.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.permalinkEnabled) {
      <span class="hljs-keyword">this</span>.permalink.parentNode.style.display = <span class="hljs-literal">null</span>;
      <span class="hljs-keyword">this</span>.permalink.href = location.toString();
    } <span class="hljs-keyword">else</span> {
      classes.push(<span class="hljs-string">'hide-permalink'</span>);
    }

    <span class="hljs-keyword">this</span>.links.className = classes.join(<span class="hljs-string">' '</span>);
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-22">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-22">&#182;</a>
              </div>
              <p>Display any warnings that were generated while rendering a regular expression.</p>
<ul>
<li><strong>warnings</strong> - Array of warning messages to display.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  displayWarnings(warnings) {
    <span class="hljs-keyword">this</span>.warnings.innerHTML = _.map(warnings, warning =&gt; (
      <span class="hljs-string">`&lt;li class="inline-icon"&gt;<span class="hljs-subst">${util.icon(<span class="hljs-string">"#warning"</span>)}</span><span class="hljs-subst">${warning}</span>&lt;/li&gt;`</span>
    )).join(<span class="hljs-string">''</span>);
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-23">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-23">&#182;</a>
              </div>
              <p>Render regular expression</p>
<ul>
<li><strong>expression</strong> - Regular expression to render</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  renderRegexp(expression) {
    <span class="hljs-keyword">let</span> parseError = <span class="hljs-literal">false</span>,
        startTime, endTime;</pre></div></div>
            
        </li>
        
        
        <li id="section-24">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-24">&#182;</a>
              </div>
              <p>When a render is already in progress, cancel it and try rendering again
after a short delay (canceling a render is not instantaneous).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.running) {
      <span class="hljs-keyword">this</span>.running.cancel();

      <span class="hljs-keyword">return</span> util.wait(<span class="hljs-number">10</span>).then(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">this</span>.renderRegexp(expression));
    }

    <span class="hljs-keyword">this</span>.state = <span class="hljs-string">'is-loading'</span>;
    util.track(<span class="hljs-string">'send'</span>, <span class="hljs-string">'event'</span>, <span class="hljs-string">'visualization'</span>, <span class="hljs-string">'start'</span>);
    startTime = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().getTime();

    <span class="hljs-keyword">this</span>.running = <span class="hljs-keyword">new</span> Parser(<span class="hljs-keyword">this</span>.svgContainer);

    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.running</pre></div></div>
            
        </li>
        
        
        <li id="section-25">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-25">&#182;</a>
              </div>
              <p>Parse the expression.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      .parse(expression)</pre></div></div>
            
        </li>
        
        
        <li id="section-26">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-26">&#182;</a>
              </div>
              <p>Display any error messages from the parser and abort the render.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      .catch(<span class="hljs-function"><span class="hljs-params">message</span> =&gt;</span> {
        <span class="hljs-keyword">this</span>.state = <span class="hljs-string">'has-error'</span>;
        <span class="hljs-keyword">this</span>.error.innerHTML = <span class="hljs-string">''</span>;
        <span class="hljs-keyword">this</span>.error.appendChild(<span class="hljs-built_in">document</span>.createTextNode(message));

        parseError = <span class="hljs-literal">true</span>;

        <span class="hljs-keyword">throw</span> message;
      })</pre></div></div>
            
        </li>
        
        
        <li id="section-27">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-27">&#182;</a>
              </div>
              <p>When parsing is successful, render the parsed expression.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      .then(<span class="hljs-function"><span class="hljs-params">parser</span> =&gt;</span> parser.render())</pre></div></div>
            
        </li>
        
        
        <li id="section-28">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-28">&#182;</a>
              </div>
              <p>Once rendering is complete:</p>
<ul>
<li>Update links</li>
<li>Display any warnings</li>
<li>Track the completion of the render and how long it took</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>      .then(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-keyword">this</span>.state = <span class="hljs-string">'has-results'</span>;
        <span class="hljs-keyword">this</span>.updateLinks();
        <span class="hljs-keyword">this</span>.displayWarnings(<span class="hljs-keyword">this</span>.running.warnings);
        util.track(<span class="hljs-string">'send'</span>, <span class="hljs-string">'event'</span>, <span class="hljs-string">'visualization'</span>, <span class="hljs-string">'complete'</span>);

        endTime = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().getTime();
        util.track(<span class="hljs-string">'send'</span>, <span class="hljs-string">'timing'</span>, <span class="hljs-string">'visualization'</span>, <span class="hljs-string">'total time'</span>, endTime - startTime);
      })</pre></div></div>
            
        </li>
        
        
        <li id="section-29">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-29">&#182;</a>
              </div>
              <p>Handle any errors that happened during the rendering pipeline.
Swallows parse errors and render cancellations. Any other exceptions
are allowed to continue on to be tracked by the global error handler.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      .catch(<span class="hljs-function"><span class="hljs-params">message</span> =&gt;</span> {
        <span class="hljs-keyword">if</span> (message === <span class="hljs-string">'Render cancelled'</span>) {
          util.track(<span class="hljs-string">'send'</span>, <span class="hljs-string">'event'</span>, <span class="hljs-string">'visualization'</span>, <span class="hljs-string">'cancelled'</span>);
          <span class="hljs-keyword">this</span>.state = <span class="hljs-string">''</span>;
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (parseError) {
          util.track(<span class="hljs-string">'send'</span>, <span class="hljs-string">'event'</span>, <span class="hljs-string">'visualization'</span>, <span class="hljs-string">'parse error'</span>);
        } <span class="hljs-keyword">else</span> {
          <span class="hljs-keyword">throw</span> message;
        }
      })</pre></div></div>
            
        </li>
        
        
        <li id="section-30">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-30">&#182;</a>
              </div>
              <p>Finally, mark rendering as complete (and pass along any exceptions
that were thrown).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      .then(
        <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
          <span class="hljs-keyword">this</span>.running = <span class="hljs-literal">false</span>;
        },
        message =&gt; {
          <span class="hljs-keyword">this</span>.running = <span class="hljs-literal">false</span>;
          <span class="hljs-keyword">throw</span> message;
        }
      );
  }
}</pre></div></div>
            
        </li>
        
    </ul>
  </div>
</body>
</html>
